#ifdef WIN32
#include <windows.h>
#endif

#ifdef MACX_DEV
#include <gl.h>
#include <glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif

#include <stdio.h>

#include "geometrydatanode.h"
#include "geometryattribewidget.h"
#include "../renderer/openglrenderer.h"

using namespace PBVP;

GeometryDataNode::GeometryDataNode(GeometryData *pGeometry, MainInterface* mainInterface)
{
	m_pGeometry = pGeometry;
	m_IsVisible = true;

	m_pAttribWidget = new GeometryAttribWidget(this);
	// Set OpenGL renderer as the default renderer
	m_pRenderer = 0;
	setRenderer(new OpenGLRenderer());
	m_pRenderer->initialize(mainInterface);
	m_pAttribWidget->setRenderingProperty(m_pRenderer->getRenderControl());

	// Find the bounding box of the geometry
	float *verts = m_pGeometry->vertexPointer();
	Vector3 minExt(verts), maxExt(verts);
	for (int i = 1; i < m_pGeometry->numOfVertices(); i++)
	{
		if (minExt.x > verts[3*i]) minExt.x = verts[3*i];
		if (minExt.y > verts[3*i+1]) minExt.y = verts[3*i+1];
		if (minExt.z > verts[3*i+2]) minExt.z = verts[3*i+2];
		if (maxExt.x < verts[3*i]) maxExt.x = verts[3*i];
		if (maxExt.y < verts[3*i+1]) maxExt.y = verts[3*i+1];
		if (maxExt.z < verts[3*i+2]) maxExt.z = verts[3*i+2];
	}
	m_BBox.setMinimum(minExt);
	m_BBox.setMaximum(maxExt);
}

GeometryDataNode::~GeometryDataNode()
{
	delete m_pGeometry;
	delete m_pRenderer;
}

QWidget* GeometryDataNode::getPropertyWidget()const
{
	return m_pAttribWidget;
}

void GeometryDataNode::render()
{
	if(!m_pRenderer) return;
	m_pRenderer->begin();
	m_pRenderer->render(this);
	m_pRenderer->end();
}

void GeometryDataNode::setRenderer(RenderPlugin * pRenderer)
{
	DataNode::setRenderer(pRenderer);
	if(pRenderer && pRenderer->getRenderControl()) {
		m_pAttribWidget->setRenderingProperty(pRenderer->getRenderControl());
	}
}

void GeometryDataNode::setData(PBVP::DataInterface *pData)
{
	GeometryData *pGeoData = dynamic_cast<GeometryData *>(pData);
	if(!pGeoData) return;	// data not in the right type. Just return.

	delete m_pGeometry;
	m_pGeometry = pGeoData;

	// Find the bounding box of the new geometry
	float *verts = m_pGeometry->vertexPointer();
	Vector3 minExt(verts), maxExt(verts);
	for (int i = 1; i < m_pGeometry->numOfVertices(); i++)
	{
		if (minExt.x > verts[3*i]) minExt.x = verts[3*i];
		if (minExt.y > verts[3*i+1]) minExt.y = verts[3*i+1];
		if (minExt.z > verts[3*i+2]) minExt.z = verts[3*i+2];
		if (maxExt.x < verts[3*i]) maxExt.x = verts[3*i];
		if (maxExt.y < verts[3*i+1]) maxExt.y = verts[3*i+1];
		if (maxExt.z < verts[3*i+2]) maxExt.z = verts[3*i+2];
	}
	m_BBox.setMinimum(minExt);
	m_BBox.setMaximum(maxExt);

	m_pAttribWidget->updateAttributes();

	emit dataChanged();
}
